package com.qwc.blog.common.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.text.CharSequenceUtil;
import com.qwc.blog.common.exception.UploadFileException;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Objects;

import static com.qwc.blog.common.constant.FileConstant.*;

/**
 * @author qiuwencong
 * @Date 2022/2/23 16:01
 * @Package com.qwc.blog.common.util
 * @Description
 */
public class FileUtils {

    private FileUtils() {
        throw new IllegalStateException("Utility class");
    }

    public static String upload(MultipartFile file, String profile, String item) throws IOException {
        if (Objects.isNull(file)||CharSequenceUtil.isBlank(file.getOriginalFilename())||file.isEmpty()) {
            throw new UploadFileException(UPLOAD_EXCEPTION);
        }
        int fileNameLength = file.getOriginalFilename().length();
        if (fileNameLength > DEFAULT_FILE_NAME_LENGTH) {
            throw new UploadFileException(FILE_NAME_LENGTH_LIMIT + DEFAULT_FILE_NAME_LENGTH);
        }
        assertAllowed(file, DEFAULT_ALLOWED_EXTENSION);
        String fileName = extractFilename(file);
        File desc = getAbsoluteFile(profile, item, fileName);
        file.transferTo(desc);
        return getPathFileName(item, fileName);
    }

    private static String getPathFileName(String item, String fileName) {
        return RESOURCE_PREFIX  + item + File.separator + fileName;
    }

    public static void assertAllowed(MultipartFile file, String[] allowedExtension) {
        long size = file.getSize();
        if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) {
            throw new UploadFileException(FILE_SIZE_LIMIT + DEFAULT_MAX_SIZE / 1024 / 1024);
        }
        String fileName = file.getOriginalFilename();
        String extension = getExtension(file);
        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) {
            throw new UploadFileException("文件名:" + allowedExtension + ",扩展:" + extension + ",允许扩展:" + fileName);
        }
    }

    public static final File getAbsoluteFile(String profile, String item, String fileName) {
        File desc = new File(profile + item + File.separator + fileName);
        if (!desc.exists() && !desc.getParentFile().exists()) {
            desc.getParentFile().mkdirs();
        }
        return desc;
    }

    /**
     * 判断MIME类型是否是允许的MIME类型
     *
     * @param extension
     * @param allowedExtension
     * @return
     */
    public static final boolean isAllowedExtension(String extension, String[] allowedExtension) {
        for (String str : allowedExtension) {
            if (str.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    public static final String getExtension(MultipartFile file) {
        String extension = FileNameUtil.extName(file.getOriginalFilename());
        if (CharSequenceUtil.isEmpty(extension)) {
            extension = getExtension(file.getContentType());
        }
        return extension;
    }

    public static String getExtension(String prefix) {
        switch (prefix) {
            case IMAGE_PNG:
                return "png";
            case IMAGE_JPG:
                return "jpg";
            case IMAGE_JPEG:
                return "jpeg";
            case IMAGE_BMP:
                return "bmp";
            case IMAGE_GIF:
                return "gif";
            default:
                return "";
        }
    }

    /**
     * 编码文件名
     */
    public static final String extractFilename(MultipartFile file) {
        String extension = getExtension(file);
        return datePath() + File.separator + fastUUID() + "." + extension;
    }

    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateUtil.format(now, "yyyy/MM/dd");
    }

    /**
     * 获取随机UUID，使用性能更好的ThreadLocalRandom生成UUID
     *
     * @return 随机UUID
     */
    public static String fastUUID() {
        return UUID.fastUUID().toString();
    }
}
